#include "unit.c"

static void alwaystrueaction(Unit* v){v->out[0].cache=1;}
static void alwaystrueupdate(Unit* v){v->out[0].value=1;}
Unit* newalwaystrue(){return newunit(0,1,alwaystrueaction,alwaystrueupdate);}
static void alwaysfalseaction(Unit* v){v->out[0].cache=0;}
static void alwaysfalseupdate(Unit* v){v->out[0].value=0;}
Unit* newalwaysfalse(){return newunit(0,1,alwaysfalseaction,alwaysfalseupdate);}

static void nand1bitaction(Unit* v){
	InPack* in=v->in,*a=&in[0],*b=&in[1];
	v->out[0].cache=!(a->in->out[a->outport].value&b->in->out[b->outport].value);
}
static void singleupdate(Unit* v){v->out[0].value=v->out[0].cache;}
Unit* newnand1bit(){
	return newunit(2,1,nand1bitaction,singleupdate);
}

static void and1bitaction(Unit* v){
	InPack* in=v->in,*a=&in[0],*b=&in[1];
	v->out[0].cache=(a->in->out[a->outport].value&b->in->out[b->outport].value)&1;
}
Unit* newand1bit(){
	return newunit(2,1,and1bitaction,singleupdate);
}

static void or1bitaction(Unit* v){
	InPack* in=v->in,*a=&in[0],*b=&in[1];
	v->out[0].cache=(a->in->out[a->outport].value|b->in->out[b->outport].value)&1;
}
Unit* newor1bit(){
	return newunit(2,1,or1bitaction,singleupdate);
}
static void xor1bitaction(Unit* v){
	InPack* in=v->in,*a=&in[0],*b=&in[1];
	v->out[0].cache=(a->in->out[a->outport].value^b->in->out[b->outport].value)&1;
}
Unit* newxor1bit(){
	return newunit(2,1,xor1bitaction,singleupdate);
}

static void notaction(Unit* v){
	InPack* in=v->in,*a=&in[0];
	v->out[0].cache=!a->in->out[a->outport].value;
}
Unit* newnot(){
	return newunit(1,1,notaction,singleupdate);
}

Unit* newrslatch(){
	Unit *out=newnand1bit(),*nand1=newnand1bit(),
	*rs=newmodule(2,1,out,0,0,nand1,1);
	connectunit(nand1,0,out,1);
	connectunit(out,0,nand1,0);
	return rs;
}